refactor(career): 経歴書 保存前確認の校正指摘機能を撤去#311
Conversation
GitHub連携ダッシュボードの提供価値が薄い集計を撤去し、コントリビューション ヒートマップを年ごとに切り替え表示できるようにする。 Part A: フレームワーク/インフラ/DevTools の検出・集計を完全削除 - repo_analyzer は言語比率算出のみ残し、検出マップ・依存パーサーを撤去 - RepoData から dependencies/root_files/detected_* を削除し、連鎖して不要に なった api_client のルートファイル/ファイル内容取得も削除 - skill_extractor を言語・トピック・説明文の3経路に限定 - pipeline/response_mapper/schema の3フィールドとダッシュボードの該当 セクション・TechBar を削除(unique_skills は依存/ルートファイル由来分が減る) Part B: ヒートマップの年次表示(全期間取得) - contributionYears で貢献のある全年を取得し、年ごとに from/to 指定で取得する fetch_all_contribution_calendars を追加(降順・失敗年はスキップ) - ContributionCalendar に year を追加し、contribution_calendar(単数) を contribution_calendars(複数) へ変更 - ダッシュボードに年セレクタを追加し選択年のヒートマップを表示 破壊的変更: GitHubLinkResponse の契約変更。cache.result は JSON のため マイグレーション不要だが、既存キャッシュは再連携するまで新表示にならない。 https://claude.ai/code/session_01JcXKiE9z433pPbUT5jsdvL
保存前の確認ダイアログから校正(誤字脱字・表記ゆれ)指摘を削除する。 ノイズが多く精度も低いため不要と判断。左右 diff・項目ごとの元に戻す等、 変更内容の確認機能自体は維持する。 - proofread サブシステム一式と kuromoji 辞書・専用ヘッダを削除 - useProofread フックと textlint/kuromoji 系 npm 依存を削除 - careerReview / diffHighlight から校正連携を剥がし diff 機能のみ残す - vite の kuromoji 配信プラグイン・worker 設定を撤去 あわせて入力モーダルのプレビュー(MarkdownFieldTrigger)を Markdown 記法除去・先頭10文字へ変更する(同居していた別作業)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 49 minutes and 51 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (13)
📒 Files selected for processing (52)
📝 WalkthroughWalkthroughThis PR: makes GitHub contribution calendars multi-year with a year field and multi-call GraphQL fetch; removes dependency/root-file fetching and framework/devtool/infra detection from the intelligence pipeline; and deletes the frontend proofreading feature and its toolchain, adjusting UI, tests, and build config accordingly. ChangesContribution Calendar Multi-Year Refactoring
Framework/DevTools/Infrastructure Detection Removal
Proofreading Feature Complete Deletion
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
- career-proofread.spec.ts を削除(校正機能の撤去に伴い対象消滅) - career-field-modal: フォームプレビューの期待値を Markdown 記法除去後の 先頭10文字(省略記号付き)に更新 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
backend/tests/test_github_collector_extended.py (1)
128-142:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAllow empty language payloads in
_mock_collect.Line 141 uses
languages or {"Python": 10000}, so callers cannot simulatefetch_languages()returning{}. That hides the collector path where a repo has no language data and makes future tests silently use a non-empty fixture instead.Proposed fix
def _mock_collect(self, raw_repos, languages=None): """collect_repos の外部 API 呼び出しをすべてモック化して実行するヘルパー。""" mock_http, _ = _mock_http_client() with ( patch("app.services.intelligence.github_collector.httpx.AsyncClient", return_value=mock_http), patch( "app.services.intelligence.github_collector.fetch_repos_raw", new_callable=AsyncMock, return_value=raw_repos, ), patch( "app.services.intelligence.github_collector.fetch_languages", new_callable=AsyncMock, - return_value=languages or {"Python": 10000}, + return_value={"Python": 10000} if languages is None else languages, ), ): return _run(collect_repos("testuser"))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/tests/test_github_collector_extended.py` around lines 128 - 142, The helper _mock_collect currently forces a non-empty languages payload by using "languages or {'Python': 10000}", which prevents tests from simulating an empty language response; change the patch for fetch_languages in _mock_collect to pass languages if it is not None, and only use the default {"Python": 10000} when languages is exactly None (e.g., use a conditional expression like languages if languages is not None else {"Python": 10000}), so callers can pass {} to simulate no-language responses while existing callers that omit languages keep the default.frontend/src/components/forms/CareerDiffModal.tsx (1)
99-115:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winMake removed-entry clicks target the injected stub.
The edited pane now includes removal stubs via
injectRemovedPlaceholders(), butscrollToPath()still searches onlydata-fp. For removed array items that means the sidebar click either does nothing or lands on the reindexed next item instead of the red removal marker.Suggested fix
const target = doc.querySelector(`[data-fp="${escaped}"]`) ?? - doc.querySelector(`[data-fp^="${escaped}."]`); + doc.querySelector(`[data-fp^="${escaped}."]`) ?? + doc.querySelector(`[data-removed="${escaped}"]`);Also applies to: 180-185
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/forms/CareerDiffModal.tsx` around lines 99 - 115, scrollToPath currently only queries elements by data-fp and misses the injected removal stubs from injectRemovedPlaceholders; update scrollToPath (using editedFrameRef and the escaped fp) to first look for the removal stub selector created by injectRemovedPlaceholders (for example a stub attribute or marker like a data-fp-removed / data-removed attribute combined with the exact fp), then fall back to the existing queries (`[data-fp="..."]` and `[data-fp^="..."]`) so clicks target the injected stub for removed array items instead of the reindexed next item.
🧹 Nitpick comments (2)
frontend/src/components/github-link/GitHubLinkDashboard.tsx (1)
106-129: ⚡ Quick winMove new Activity labels to message SSoT constants.
Line 116, Line 121, and Line 125 add new user-facing literals directly in JSX. Please route these through centralized message constants instead of inline strings.
As per coding guidelines, "In frontend code, follow message management rules ... message literals are forbidden and must use Single Source of Truth (SSoT)."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/github-link/GitHubLinkDashboard.tsx` around lines 106 - 129, The JSX in GitHubLinkDashboard uses inline user-facing strings ("Activity", the select aria-label "表示する年", and the option label suffix "年") — move these to the centralized message SSoT constants and reference them instead; update the component to import the message keys (e.g., ACTIVITY_LABEL, YEAR_SELECT_ARIA, YEAR_SUFFIX) and replace the literals in the h2, select aria-label, and option display (currently inside the map over result.contribution_calendars) while leaving behavior tied to selectedYear, setSelectedYear, and the active calendar logic unchanged.Source: Coding guidelines
frontend/src/components/github-link/ContributionHeatmap.tsx (1)
59-59: ⚡ Quick winUse centralized message definitions for the new year-based labels.
The new visible/ARIA text is embedded directly in JSX templates. Please move these strings to the frontend message SSoT constants and compose them from there.
As per coding guidelines, "In frontend code, follow message management rules ... message literals are forbidden and must use Single Source of Truth (SSoT)."
Also applies to: 70-70
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/github-link/ContributionHeatmap.tsx` at line 59, The JSX currently embeds literal year-based labels (e.g., in ContributionHeatmap.tsx at the div with className styles.statLabel and the ARIA text on the other line) which violates the SSoT message rule; replace these literals with calls to the frontend message constants (compose a parameterized message like contributionYear or contributionYearAria in your messages/SSoT module) and pass calendar.year as the parameter, then import and use those message constants in ContributionHeatmap.tsx to render both the visible label and the ARIA text.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/services/intelligence/github_link_service.py`:
- Around line 130-133: The code incorrectly treats an empty calendars list as a
fetch failure; change the logic so cache.warning_message is set only on an
actual fetch error (e.g., exception or explicit failure result) rather than when
calendars is falsy. Update the call site (where fetch_all_contribution_calendars
is invoked and cache.warning_message is set) to inspect a success flag or catch
exceptions from fetch_all_contribution_calendars (or change
fetch_all_contribution_calendars to return a (success, calendars) result) and
only call get_error("github_link.contribution_fetch_failed") when the fetch
failed, not when calendars == [] while token exists; keep existing variables
like token, calendars, cache.warning_message and the get_error call to locate
and implement the change.
In `@backend/tests/test_github_link.py`:
- Around line 157-168: The test test_only_language_topic_description_sources is
vacuous because it asserts sources <= {"language","topic","description"} and
would pass if extract_skills returned no skills; change the assertion to require
the exact set of sources produced by the fixture (e.g., assert sources ==
{"language","topic","description"}) and optionally assert result.skills is
non-empty to ensure the three source paths in extract_skills are actually
exercised.
In `@frontend/src/components/forms/CareerDiffModal.tsx`:
- Around line 91-92: The current row key built from path + kind collides when
buildReviewEntries(changes) yields multiple changes for the same path; update
the key used when rendering reviewEntries to include a unique identifier per
change (for example append the change's id/uid or the item's index in the
grouped array) instead of only path+kind so duplicate-path modified entries get
distinct keys; search for usages of reviewEntries and the key expression
(formerly `${path}-${kind}`) in the component (also update the similar key at
the other occurrence referenced around the second spot) and replace it with
something like `${path}-${kind}-${change.id || idx}` to ensure stable, unique
keys.
---
Outside diff comments:
In `@backend/tests/test_github_collector_extended.py`:
- Around line 128-142: The helper _mock_collect currently forces a non-empty
languages payload by using "languages or {'Python': 10000}", which prevents
tests from simulating an empty language response; change the patch for
fetch_languages in _mock_collect to pass languages if it is not None, and only
use the default {"Python": 10000} when languages is exactly None (e.g., use a
conditional expression like languages if languages is not None else {"Python":
10000}), so callers can pass {} to simulate no-language responses while existing
callers that omit languages keep the default.
In `@frontend/src/components/forms/CareerDiffModal.tsx`:
- Around line 99-115: scrollToPath currently only queries elements by data-fp
and misses the injected removal stubs from injectRemovedPlaceholders; update
scrollToPath (using editedFrameRef and the escaped fp) to first look for the
removal stub selector created by injectRemovedPlaceholders (for example a stub
attribute or marker like a data-fp-removed / data-removed attribute combined
with the exact fp), then fall back to the existing queries (`[data-fp="..."]`
and `[data-fp^="..."]`) so clicks target the injected stub for removed array
items instead of the reindexed next item.
---
Nitpick comments:
In `@frontend/src/components/github-link/ContributionHeatmap.tsx`:
- Line 59: The JSX currently embeds literal year-based labels (e.g., in
ContributionHeatmap.tsx at the div with className styles.statLabel and the ARIA
text on the other line) which violates the SSoT message rule; replace these
literals with calls to the frontend message constants (compose a parameterized
message like contributionYear or contributionYearAria in your messages/SSoT
module) and pass calendar.year as the parameter, then import and use those
message constants in ContributionHeatmap.tsx to render both the visible label
and the ARIA text.
In `@frontend/src/components/github-link/GitHubLinkDashboard.tsx`:
- Around line 106-129: The JSX in GitHubLinkDashboard uses inline user-facing
strings ("Activity", the select aria-label "表示する年", and the option label suffix
"年") — move these to the centralized message SSoT constants and reference them
instead; update the component to import the message keys (e.g., ACTIVITY_LABEL,
YEAR_SELECT_ARIA, YEAR_SUFFIX) and replace the literals in the h2, select
aria-label, and option display (currently inside the map over
result.contribution_calendars) while leaving behavior tied to selectedYear,
setSelectedYear, and the active calendar logic unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 57bef127-d550-4a57-a8d5-ee1a253fa4c0
⛔ Files ignored due to path filters (13)
frontend/package-lock.jsonis excluded by!**/package-lock.jsonfrontend/public/kuromoji-dict/base.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/cc.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/check.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/tid.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/tid_map.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/tid_pos.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/unk.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/unk_char.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/unk_compat.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/unk_invoke.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/unk_map.dat.gzis excluded by!**/*.gzfrontend/public/kuromoji-dict/unk_pos.dat.gzis excluded by!**/*.gz
📒 Files selected for processing (50)
backend/app/schemas/github_link.pybackend/app/services/intelligence/github/__init__.pybackend/app/services/intelligence/github/api_client.pybackend/app/services/intelligence/github/contributions.pybackend/app/services/intelligence/github/repo_analyzer.pybackend/app/services/intelligence/github_collector.pybackend/app/services/intelligence/github_link_service.pybackend/app/services/intelligence/pipeline.pybackend/app/services/intelligence/response_mapper.pybackend/app/services/intelligence/skill_extractor.pybackend/tests/test_contributions.pybackend/tests/test_github_collector_extended.pybackend/tests/test_github_link.pybackend/tests/test_repo_analyzer.pybackend/tests/test_worker/test_github_link.pyfrontend/e2e/github-link.spec.tsfrontend/package.jsonfrontend/public/_headersfrontend/src/api/generated.tsfrontend/src/api/types.tsfrontend/src/components/forms/CareerDiffModal.module.cssfrontend/src/components/forms/CareerDiffModal.tsxfrontend/src/components/forms/CareerResumeForm.tsxfrontend/src/components/forms/MarkdownFieldTrigger.tsxfrontend/src/components/github-link/ContributionHeatmap.test.tsxfrontend/src/components/github-link/ContributionHeatmap.tsxfrontend/src/components/github-link/GitHubLinkDashboard.module.cssfrontend/src/components/github-link/GitHubLinkDashboard.test.tsxfrontend/src/components/github-link/GitHubLinkDashboard.tsxfrontend/src/components/github-link/TechBar.test.tsxfrontend/src/components/github-link/TechBar.tsxfrontend/src/constants/messages.tsfrontend/src/hooks/career/useProofread.test.tsfrontend/src/hooks/career/useProofread.tsfrontend/src/proofread/collectCareerTexts.test.tsfrontend/src/proofread/collectCareerTexts.tsfrontend/src/proofread/issueFormat.test.tsfrontend/src/proofread/issueFormat.tsfrontend/src/proofread/prh-it-terms.ymlfrontend/src/proofread/proofread.worker.tsfrontend/src/proofread/proofreadClient.tsfrontend/src/proofread/textlint-modules.d.tsfrontend/src/proofread/types.tsfrontend/src/proofread/worker-env-polyfill.tsfrontend/src/test/handlers.tsfrontend/src/utils/careerReview.test.tsfrontend/src/utils/careerReview.tsfrontend/src/utils/diffHighlight.test.tsfrontend/src/utils/diffHighlight.tsfrontend/vite.config.ts
💤 Files with no reviewable changes (22)
- frontend/src/proofread/textlint-modules.d.ts
- frontend/src/proofread/collectCareerTexts.ts
- frontend/public/_headers
- frontend/src/proofread/proofreadClient.ts
- frontend/src/proofread/worker-env-polyfill.ts
- frontend/src/proofread/collectCareerTexts.test.ts
- frontend/src/proofread/types.ts
- frontend/src/proofread/issueFormat.test.ts
- frontend/src/components/github-link/TechBar.tsx
- frontend/src/components/github-link/TechBar.test.tsx
- frontend/src/hooks/career/useProofread.test.ts
- frontend/src/components/forms/CareerResumeForm.tsx
- frontend/src/hooks/career/useProofread.ts
- frontend/src/proofread/prh-it-terms.yml
- frontend/src/components/forms/CareerDiffModal.module.css
- frontend/src/proofread/issueFormat.ts
- backend/app/services/intelligence/skill_extractor.py
- frontend/src/proofread/proofread.worker.ts
- backend/app/services/intelligence/pipeline.py
- frontend/src/constants/messages.ts
- backend/app/services/intelligence/response_mapper.py
- frontend/src/utils/diffHighlight.test.ts
backend:
- fetch_all_contribution_calendars を (success, calendars) 返却に変更し、
「取得失敗」と「貢献年ゼロ」を区別。貢献ゼロで warning を立てない
- 取得成功・空カレンダーで warning が立たない回帰テストを追加
- test_only_language_topic_description_sources を厳密化
(3経路発火 + source 完全一致 + skills 非空)
- _mock_collect を languages is not None 判定にし {} で空言語応答を再現可能に
frontend:
- CareerDiffModal: 同一パス複数差分での key 衝突を index 付与で回避
- CareerDiffModal: scrollToPath が削除スタブ(data-removed)を優先参照し、
繰り上がった別項目へスクロールしないよう修正
- ContributionHeatmap / GitHubLinkDashboard のリテラル文言を
messages.ts の SSoT 定数・関数へ移動
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@coderabbitai rvして |
|
✅ Action performedFull review finished. |
概要
経歴書の保存前確認ダイアログから校正(誤字脱字・表記ゆれ)指摘機能を撤去します。ノイズが多く精度も低いため不要と判断しました。左右 diff・項目ごとの「元に戻す」など、変更内容の確認機能そのものは維持します。
変更内容
校正機能の撤去
src/proofread/一式(textlint / kuromoji worker・収集・整形)を削除public/kuromoji-dict/(辞書13ファイル)・public/_headers(kuromoji 配信専用ヘッダ)を削除useProofreadフック+テストを削除package.json+ lockfile)careerReview.ts/diffHighlight.tsから校正連携を剥がし、diff 機能のみ残すCareerDiffModal/CareerResumeForm/messages.ts/ 関連 CSS・テストから校正部分を削除.ts/.js両方)あわせて(同居していた別作業)
MarkdownFieldTriggerの入力プレビューを Markdown 記法除去・先頭10文字 に変更確認
make ci(lint / 273 tests / build)greenmake lint-frontend-messagesgreen🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Changes
Removed
Tests